package com.example.rbac.interceptor;

import com.example.rbac.annotation.RequirePermission;
import com.example.rbac.exception.CustomException;
import com.example.rbac.service.UserService;
import com.example.rbac.utils.JwtUtils;
import com.example.rbac.utils.UserContext;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;

@Component
public class PermissionInterceptor implements HandlerInterceptor {
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private UserService userService;
    
    @Value("${jwt.token-header}")
    private String tokenHeader;
    
    @Value("${jwt.token-prefix}")
    private String tokenPrefix;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 检查是否是OPTIONS请求，直接放行
        if (request.getMethod().equals("OPTIONS")) {
            return true;
        }
        
        // 不是Controller方法，直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        
        // 检查请求路径是否为登录、注册或Swagger相关路径，如果是，直接放行
        String path = request.getRequestURI();
        if (path.contains("/auth/login") || path.contains("/auth/register") || 
            path.contains("/swagger-resources/") || path.contains("/webjars/") || 
            path.contains("/swagger/") || path.contains("/v3/") ||
            path.contains("/swagger-ui/") || path.contains("/springfox/") ||
            path.contains("/swagger-ui.html")|| path.contains("/register/login")) {
            return true;
        }
        
        // 从请求头中获取token
        String token = request.getHeader(tokenHeader);
        if (token == null) {
            throw new CustomException(401, "请先登录");
        }
        
        // 如果有前缀，移除token前缀
        if (tokenPrefix != null && !tokenPrefix.isEmpty() && token.startsWith(tokenPrefix)) {
            token = token.substring(tokenPrefix.length());
        }
        
        try {
            // 解析token
            Claims claims = jwtUtils.parseToken(token);
            Long userId = jwtUtils.getUserIdFromToken(token);
            
            // 检查token是否过期
            if (jwtUtils.isTokenExpired(token)) {
                throw new CustomException(401, "token已过期，请重新登录");
            }
            
            // 检查方法是否需要权限
            RequirePermission permissionAnnotation = handlerMethod.getMethodAnnotation(RequirePermission.class);
            if (permissionAnnotation != null) {
                // 获取用户拥有的权限
                Set<String> userPermissions = userService.getPermissionsByUserId(userId);
                
                // 检查用户是否有访问权限
                if (!userPermissions.contains(permissionAnnotation.value())) {
                    throw new CustomException(403, "无权限访问");
                }
            }
            
            // 将用户信息存入ThreadLocal，方便后续使用
            UserContext.setUserId(userId);
            UserContext.setUsername(claims.getSubject());
            
        } catch (Exception e) {
            if (e instanceof CustomException) {
                throw e;
            }
            throw new CustomException(401, "token无效");
        }
        
        return true;
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 清理ThreadLocal中的数据，防止内存泄漏
        UserContext.clear();
    }
}
